package com.koelo.kiss.re.spring;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.springframework.core.io.ClassPathResource;

public class PropertyReader {
	
	private String location;
	private Set<Properties> sessions;

	public PropertyReader(String location) {

		setLocation(location);
	}
	
	public PropertyReader() {
		
		this(null);
	}
	
	public final void setLocation(String location) {
		
		this.location = location;
	}
	
	public final String getLocation() {
		
		return this.location;
	}
	
	@SuppressWarnings("serial")
	public Set<Properties> getProperties() 
		throws Exception {
		
		if (this.sessions != null) {
			return this.sessions;
		}
		if (getLocation() == null) {
			throw new IllegalArgumentException("Argument location not found. Use property location to set it.");
		}
		this.sessions = new HashSet<Properties>();
		Properties session = null;
		final Properties context = new Properties();
		File file = (new ClassPathResource(getLocation())).getFile();
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);
		String input = br.readLine();
		while (input != null) {
			input = input.trim();
			if (!input.equals("") && !input.startsWith("#")) {
				if (input.startsWith("[") && input.endsWith("]")) {
					if (session != null) {
						this.sessions.add(session);
					}
					session = new NamedProperties(input.replace("[", "").replace("]", ""), context);
				} else {
					String key = "";
					String value = "";
					String[] tokens = input.split("=");
					key = tokens[0];
					if (tokens.length >= 2) {
						for (int i = 1; i < tokens.length; i++) {
							value += tokens[i];
						}
					}
					if (session == null) {
						context.setProperty(key, value);
					} else {
						session.setProperty(key, value);
					}
				}
			}
			input = br.readLine();
		}
		if (session != null) {
			this.sessions.add(session);
		}
		br.close();
		isr.close();
		fis.close();
		return this.sessions.size() > 0 ? this.sessions : new HashSet<Properties>() {{add(context);}};
	}
	
	public Set<Properties> getProperties(String name) 
		throws Exception {
		
		Set<Properties> results = new HashSet<Properties>();
		Set<Properties> properties = getProperties();
		for (Properties props: properties) {
			if (((NamedProperties) props).getName().equals(name)) {
				results.add(props);
			}
		}
		return results;
	}
}
